Skip to content

feat: kaspa support#8786

Open
rohitsaw115 wants to merge 1 commit into
masterfrom
kaspa-support
Open

feat: kaspa support#8786
rohitsaw115 wants to merge 1 commit into
masterfrom
kaspa-support

Conversation

@rohitsaw115
Copy link
Copy Markdown
Contributor

@rohitsaw115 rohitsaw115 commented May 18, 2026

ticket: cecho-1071

Summary
This PR implements full support for the Kaspa (KASPA) coin in the BitGoJS SDK, including transaction building, per-input Schnorr signing, PSKT (Partially Signed Kaspa Transaction) support, and comprehensive test coverage.

Key changes
PSKT — Kaspa's native PSBT equivalent (src/lib/pskt.ts, 590 lines new)

  • Implements PSKT from scratch in TypeScript with zero new dependencies, matching the camelCase JSON wire format of rusty-kaspa's wallet/pskt crate
  • Full role state machine: CREATOR → UPDATER → SIGNER → COMBINER → FINALIZER → EXTRACTOR
  • sign(privateKey) — direct single-key path; computes a distinct keyed Blake2b-256 sighash per input (Kaspa's BIP-143-like per-input scheme)
  • addSignature(index, pubKey, sig) — HSM / TSS external signing path; the unsigned PSKT JSON is the only artifact that needs to travel to the signer and back
  • combine(other) — Combiner role merges partialSigs from independent signers without conflicts
    finalize() — Finalizer promotes partialSigs → finalScriptSig with Kaspa's push-only opcode (0x41 + 64-byte Schnorr sig + sighash type)
  • extract() — Extractor emits the exact broadcast JSON accepted by the Kaspa node REST API
  • serialize() / Pskt.deserialize() — JSON round-trip for hand-off between coordinator and HSM/TSS service

Sighash (src/lib/sighash.ts)

  • Rewrote to match rusty-kaspa's authoritative implementation: all intermediate and final hashes use keyed Blake2b-256 with key "TransactionSigningHash" — verified to produce signatures that the Kaspa testnet node accepts

Transaction (src/lib/transaction.ts)

  • Per-input Schnorr signing loop in sign() with push-only signatureScript layout (0x41 + 64-byte sig + sighash type)
  • addSignatureForInput() for the TSS multi-input path
  • signablePayloads getter returning one sighash Buffer per input for MPCv2 (DKLS) sessions
  • toPskt() / Transaction.fromPskt() bridge methods to/from PSKT

TransactionBuilder (src/lib/transactionBuilder.ts)

  • toPskt() — builds the transaction and returns it as an unsigned PSKT at UPDATER role, ready for HSM hand-off

Tests

  • test/unit/pskt.test.ts — 27 new tests covering full role flow, serialize/deserialize round-trip, combine() conflict detection, addSignature() HSM path, and verifying that PSKT extract() output is byte-identical to Transaction.toBroadcastFormat()
  • test/unit/coin.test.ts — signTransaction tests covering direct private key path (Path A), per-input TSS signatures path (Path B), partial signing returning halfSigned
  • Extended transactionFlow.test.ts and transaction.test.ts with multi-input signing and per-input Schnorr verification

@rohitsaw115 rohitsaw115 force-pushed the kaspa-support branch 4 times, most recently from 7383a6f to 1a0282b Compare May 18, 2026 06:21
@rohitsaw115 rohitsaw115 marked this pull request as ready for review May 18, 2026 10:27
@rohitsaw115 rohitsaw115 requested review from a team as code owners May 18, 2026 10:27
Comment on lines -45 to -54
getChain(): string {
return this._staticsCoin.name;
}
/**
* Human-readable name for this coin variant.
* Implemented in each concrete class to avoid runtime name comparisons.
*/
abstract getFullName(): string;

getFamily(): CoinFamily {
return this._staticsCoin.family;
}
/**
* Whether this is a mainnet or testnet coin.
* Implemented in each concrete class to avoid runtime name comparisons.
*/
protected abstract isMainnet(): boolean;

getFullName(): string {
return this._staticsCoin.fullName;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why these functions are removed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants